/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package edu.pdx.cs.guavadata;

import edu.pdx.cs.guavadata.query.Command;
import edu.pdx.cs.guavadata.query.Operator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;

/**
 * Represent the transaction, it could either be one command, or multiple command.
 * if it's multiple commands, those commands was stored in replace
 * @author VuTran
 */
public class Transaction {
    List<Command> contents;
    Dictionary<Command, Collection<Command>> replace;

    public List<Command> getContents() {
        return contents;
    }

    public void setContents(List<Command> contents) {
        this.contents = contents;
    }

    public Transaction() {
        contents = new ArrayList<Command>();
        replace = new Hashtable<Command, Collection<Command>>();
    }

    public Transaction(Transaction t) {
        contents = new ArrayList<Command>(t.contents);
        replace = new Hashtable<Command, Collection<Command>>();
    }

    public Transaction(Collection<Command> commands) {
        contents = new ArrayList<Command>(commands);
        replace = new Hashtable<Command, Collection<Command>>();
    }

    /*
     * Shortcut for generating a transaction from a single operator
     */
    public Transaction(Operator o) {
        Command c = new Command(o);
        contents = new ArrayList<Command>();
        this.add(c);
        replace = new Hashtable<Command, Collection<Command>>();
    }

    public void add(Command c) {
        c.container = this;
        contents.add(c);
    }

    public void notifyChange(Command o, Command...onew) {
        replace.put(o, Arrays.asList(onew));
    }

    public void complete() {
        // Go through the list of commands and replace the ones that need replacing
        List<Command> newList = new ArrayList<Command>();
        for (Command c : this.contents) {
            if (replace.get(c) != null)
                newList.addAll(replace.get(c));
            else
                newList.add(c);
        }

        for (Command c : newList) {
            c.container = this;
        }

        contents = newList;
    }
}
